import 'package:dio/dio.dart';
import 'ApiException.dart';
import 'HttpInterceptor.dart';

class Http {
  // 单例模式
  static final Http _instance = Http._internal();

  factory Http() => _instance;

  Http._internal() {
    init();
  }

  late Dio dio;

  // dio 的初始化
  void init() {
    BaseOptions options = BaseOptions(
      baseUrl: "https://www.wanandroid.com", // 你的 API Base URL
      connectTimeout: Duration(seconds: 10), // 10秒连接超时
      receiveTimeout: Duration(seconds: 5), // 5秒接收超时
      headers: {
        // 你可以设置一些公共的 headers
        'Content-Type': 'application/json; charset=utf-8',
      },
    );

    dio = Dio(options);

    // 在这里可以添加拦截器
    dio.interceptors.add(HttpInterceptor());
  }

  // 封装通用的网络请求方法
  Future<T> request<T>(
    String path, {
    String method = 'GET',
    Map<String, dynamic>? queryParameters,
    dynamic data,
    // 用于 JSON 解析的函数
    T Function(dynamic json)? fromJsonT,
  }) async {
    try {
      final Response response = await dio.request(
        path,
        queryParameters: queryParameters,
        data: data,
        options: Options(method: method),
      );

      // onResponse 拦截器已经处理了业务成功的情况，
      // response.data 就是我们需要的业务数据 `data` 字段的内容。
      // 如果 fromJsonT 不为 null，则进行模型转换
      if (fromJsonT != null) {
        return fromJsonT(response.data);
      }
      return response.data as T;
    } on DioException catch (e) {
      // onError 拦截器已经将所有错误都转换成了 ApiException
      // 我们只需要重新抛出这个 ApiException
      throw e.error as ApiException;
    } catch (e) {
      // 其他未知错误
      throw ApiException(-1, "未知错误: $e");
    }
  }

  // 方便调用的 get 和 post 方法
  Future<T> get<T>(String path,
      {Map<String, dynamic>? queryParameters,
      T Function(dynamic json)? fromJsonT}) {
    return request(path,
        method: 'GET', queryParameters: queryParameters, fromJsonT: fromJsonT);
  }

  Future<T> post<T>(String path,
      {dynamic data, T Function(dynamic json)? fromJsonT}) {
    return request(path, method: 'POST', data: data, fromJsonT: fromJsonT);
  }
}
